const fs = require('fs')
const path = require('path')
const request = require('request')
const express = require('express')
const multer = require('multer')
const { v4: uuidv4 } = require('uuid')
const archiver = require('archiver')
const app = express()

app.use(express.static(path.join(__dirname, 'public')))
const uploads = multer({ dest: path.join(__dirname, 'newDir') })

// 上传 md 文件接口
app.post('/urlToLocal', uploads.single('md'), (req, ress) => {
  const uuid = uuidv4() 
  // 属于本次用户临时文件夹名字
  const uPath = path.join(__dirname, 'newDir', uuid) 
  // 获取上传 md 文件路径
  const filePath = req.file.path 

  // 读取 md 文件内容
  fs.readFile(filePath, (err, data) => { 
    const mdStr = data.toString()

    // 提取所有图片链接字符串
    const imgURLList = mdStr.match(/!\[.+?\]\(.+?\)/g)

    // 先准备文件夹-存放图片（req.body.path 是用户指定要存入的文件安名字）
    const imagesPath = path.join(uPath, req.body.path)
    // 如果没有这个文件夹则创建
    if (!fs.existsSync(uPath)) {
      fs.mkdirSync(uPath)
      fs.mkdirSync(imagesPath)
    }

    // 下载图片
    let finishCount = 0
    imgURLList.forEach(item => {
      const imgUrl = item.match(/\(.+?\)/)[0].replace(/[\(\)]/g, '')
      // 把图片链接地址解码 unicode
      const imgURLStr = decodeURI(path.basename(imgUrl))
      // 下载图片到保存笔记图片文件夹内
      request(imgUrl).pipe(fs.createWriteStream(path.join(imagesPath, imgURLStr)).on("close", function (err, res) {
        finishCount++
        // 所有图片下载完毕
        if (finishCount === imgURLList.length) {
          // 把字符串替换还原回去 md 内容，拼接 image 相对路径
          const allStr = mdStr.replace(/!\[.+?\]\(.+?\)/g, target => {
            const imageName = decodeURI(path.basename(target))
            const imgName = imageName.substring(0, imageName.length - 1)
            // 替换()里图片名字为路径+图片名
            const imgNameMdStr = target.replace(/\(.+?\)/, `(${req.body.path}/${imgName})`)
            return imgNameMdStr
          })
          // 写入整个 md 文件内容
          fs.writeFile(path.join(uPath, Buffer.from(req.file.originalname, "latin1").toString(
            "utf8"
          )), allStr, err => {
            // 打包 zip 开始
            // 创建可写流来写入数据
            const output = fs.createWriteStream(path.join(__dirname, `public/zip/${uuid}.zip`))// 将压缩包保存到当前项目的目录下，并且压缩包名
            const archive = archiver('zip', { zlib: { level: 9 } })// 设置压缩等级
            
            archive.pipe(output) // 建立管道连接

            archive.directory(uPath, uuid) // 压缩目录到压缩包中

            archive.finalize() // 完成压缩

            archive.on('end', function () { // 监听压缩完成
              setTimeout(() => {
                ress.download(`public/zip/${uuid}.zip`, 'md.zip', function (err) {})
              }, 500)
            })
          })
        }
      }))
    })
  })
})
app.listen(6699)
